package com.hsyt.pfc.redis.set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Collection;
import java.util.Set;

/**
 * @Description: redis set 操作接口
 * @ClassName: RedisSetHandler
 * @Package: com.hsyt.pfc.redis.set
 * @Author: wangze@hsyuntai.com
 * @Date: 2018/8/10 11:43
 * @Copyright: 版权归 HSYUNTAI 所有
 */
@Component
public class RedisSetHandler {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static StringRedisTemplate stringRedisTemplate;

    @PostConstruct
    private void init() {
        stringRedisTemplate = this.redisTemplate;
    }

    public StringRedisTemplate getRedisTemplate() {
        return redisTemplate;
    }

    public void setRedisTemplate(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * @Description: Set（集合）： 将一个或多个元素加入到集合key中，已经存在于集合中的member元素将被忽略
     * 				 假如 key 不存在，则创建一个只包含 member 元素作成员的集合。
     * 			          当 key 不是集合类型时，返回一个错误。
     * @param key
     * @param values
    * @Author: wangze@hsyuntai.com
     * @Date: 2015年11月13日 上午11:25:06
     */
    public static void sAdd(final String key, String... values){
        stringRedisTemplate.opsForSet().add(key, values);
    }

    /**
     * @Description: Set（集合）： 移除并返回集合的一个随机元素，如果只想获取一个随机元素，但不想该元素从集合中被移除的话，可以使用 sRandMember()方法。
     * @param key
    * @Author: wangze@hsyuntai.com
     * @Date: 2015年11月13日 上午11:30:34
     */
    public static String sPop(final String key){
        return stringRedisTemplate.opsForSet().pop(key);
    }

    /**
     * @Description: Set（集合）： 如果命令执行时，只提供了 key 参数，那么返回集合中的一个随机元素。
     * 				如果 count 为正数，且小于集合基数，那么命令返回一个包含 count 个元素的数组，数组中的元素各不相同。如果 count 大于等于集合基数，那么返回整个集合。
     * 				如果 count 为负数，那么命令返回一个数组，数组中的元素可能会重复出现多次，而数组的长度为 count 的绝对值
     * 				该操作和 SPOP 相似，但 SPOP 将随机元素从集合中移除并返回，而 SRANDMEMBER 则仅仅返回随机元素，而不对集合进行任何改动。
     * @param key
     * @param count
     * @return
    * @Author: wangze@hsyuntai.com
     * @Date: 2015年11月13日 上午11:35:46
     */
    public static Set<String> sRandMember(final String key,long count){
        return stringRedisTemplate.opsForSet().distinctRandomMembers(key, count);
    }

    /**
     * @Description: Set（集合）： 返回一个集合的全部成员，该集合是所有给定集合之间的差集。
     * 				 不存在的 key 被视为空集。
     * @param key
     * @param otherKey
    * @Author: wangze@hsyuntai.com
     * @Date: 2015年11月13日 下午1:29:51
     */
    public static Set<String> sDiff(final String key,String otherKey){
        return stringRedisTemplate.opsForSet().difference(key, otherKey);
    }

    /**
     * @Description: Set（集合）： 这个命令的作用和 SDIFF 类似，但它将结果保存到 destination 集合，而不是简单地返回结果集。
     * 					如果 destination 集合已经存在，则将其覆盖。
     * 					destination 可以是 key 本身。
     * @param key
     * @param otherKey
     * @param destKey
     * @return
    * @Author: wangze@hsyuntai.com
     * @Date: 2015年11月13日 下午1:32:16
     */
    public static long sDiffStore(final String key,String otherKey,String destKey){
        return stringRedisTemplate.opsForSet().differenceAndStore(key, otherKey, destKey);
    }

    /**
     * @Description: Set（集合）： 这个命令的作用和 SDIFF 类似，但它将结果保存到 destination 集合，而不是简单地返回结果集。
     * 					如果 destination 集合已经存在，则将其覆盖。
     * 					destination 可以是 key 本身。
     * @param key
     * @param otherKey
     * @param destKey
     * @return
    * @Author: wangze@hsyuntai.com
     * @Date: 2015年11月13日 下午1:37:11
     */
    public static long sDiffStore(final String key, Collection<String> otherKey, String destKey){
        return stringRedisTemplate.opsForSet().differenceAndStore(key,otherKey,destKey);
    }

    /**
     * @Description: Set（集合）： 判断 member 元素是否集合 key 的成员
     * @param key
     * @param member
     * @return
    * @Author: wangze@hsyuntai.com
     * @Date: 2015年11月13日 下午1:39:14
     */
    public static boolean sIsMember(final String key,Object member){
        return stringRedisTemplate.opsForSet().isMember(key, member);
    }

    /**
     * @Description: Set（集合）： 返回集合 key 中的所有成员。 不存在的 key 被视为空集合。
     * @param key
     * @return
    * @Author: wangze@hsyuntai.com
     * @Date: 2015年11月13日 下午1:46:31
     */
    public static Set<String> sMembers(final String key){
        return stringRedisTemplate.opsForSet().members(key);
    }

    /**
     * @Description: Set（集合）： 将 member 元素从 source 集合移动到 destination 集合
     * 							如果 source 集合不存在或不包含指定的 member 元素，则 SMOVE 命令不执行任何操作，仅返回 0 。否则， member 元素从 source 集合中被移除，并添加到 destination 集合中去。
     * 							当 destination 集合已经包含 member 元素时， SMOVE 命令只是简单地将 source 集合中的 member 元素删除。
     * 							当 source 或 destination 不是集合类型时，返回一个错误。
     * 							如果 member 元素被成功移除，返回 1 。
     * 							如果 member 元素不是 source 集合的成员，并且没有任何操作对 destination 集合执行，那么返回 0 。
     * @param source
     * @param member
     * @param destination
     * @return
    * @Author: wangze@hsyuntai.com
     * @Date: 2015年11月13日 下午1:50:50
     */
    public static boolean sMove(final String source,String member,String destination){
        return stringRedisTemplate.opsForSet().move(source,member,destination);
    }

    /**
     * @Description: Set（集合）： 移除集合 key 中的一个或多个 member 元素，不存在的 member 元素会被忽略。
     * 							当 key 不是集合类型，返回一个错误
     * 							返回被成功移除的元素的数量，不包括被忽略的元素。
     * @param key
     * @param values
     * @return
    * @Author: wangze@hsyuntai.com
     * @Date: 2015年11月13日 下午1:54:59
     */
    public static long sRem(final String key,Object... values){
        return stringRedisTemplate.opsForSet().remove(key, values);
    }

}
